package com.googlecode.spruce.schedule;

import java.io.Serializable;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerContext;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor;
import org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationResult;

import com.googlecode.spruce.core.ServiceCheckResult;
import com.googlecode.spruce.dao.ServiceGroupScheduleDao;
import com.googlecode.spruce.domain.Service;
import com.googlecode.spruce.domain.ServiceGroupSchedule;
import com.googlecode.spruce.results.ResultsService;

public class RemotePluginJob implements Job, Serializable
{
    private static final Logger logger = LoggerFactory.getLogger(RemotePluginJob.class);

    /**
     * Serial ID
     */
    private static final long serialVersionUID = 4397070909602341743L;

    @Override
    public void execute(final JobExecutionContext context) throws JobExecutionException
    {
        final JobDataMap jobDataMap = context.getMergedJobDataMap();

        final Integer scheduleID = jobDataMap.getInt("serviceGroupScheduleID");

        SchedulerContext schedulerContext;
        try
        {
            schedulerContext = context.getScheduler().getContext();
        }
        catch (final SchedulerException se)
        {
            logger.error("Scheduler exception", se);
            return;
        }

        final ServiceGroupScheduleDao scheduleDao = (ServiceGroupScheduleDao) schedulerContext
                .get("serviceGroupScheduleDao");

        final ResultsService resultsService = (ResultsService) schedulerContext.get("resultsService");

        final ServiceGroupSchedule schedule = scheduleDao.findByIDInitialized(scheduleID);

        final HttpInvokerClientConfiguration cfg = new HttpClientConfig("http://" + schedule.getHost().getIpAddress()
                + ":8090/systemcheck");

        final org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
        final CommonsHttpInvokerRequestExecutor executor = new CommonsHttpInvokerRequestExecutor(client);

        for (final Service service : schedule.getServiceGroup().getService())
        {
            try
            {
                final RemoteInvocation ri = new RemoteInvocation("performServiceCheck", new Class[]
                { String.class }, new Object[]
                { service.getPluginName() });

                final RemoteInvocationResult result = executor.executeRequest(cfg, ri);

                if (logger.isDebugEnabled())
                {
                    logger.debug("Result: " + result.getValue());
                }

                if (result.hasException())
                {
                    logger.error("Error!", result.getException());
                }

                final ServiceCheckResult checkResult = (ServiceCheckResult) result.getValue();

                resultsService.register(checkResult);
            }
            catch (final Exception e)
            {
                logger.error("Error in running a plugin", e);
            }
        }
    }

    /**
     * 
     * 
     */
    private static class HttpClientConfig implements HttpInvokerClientConfiguration
    {
        private final String serviceUrl;

        public HttpClientConfig(final String serviceUrl)
        {
            this.serviceUrl = serviceUrl;
        }

        @Override
        public String getServiceUrl()
        {
            return this.serviceUrl;
        }

        @Override
        public String getCodebaseUrl()
        {
            return null;
        }
    }

}